104.変数ベース+配列+2種類(HELL)

変数ベースで2種類のキャラを配列管理すると、地獄のような複雑さになります。

p5.js oop
Learning OOP Object Oriented Programming

2種類のキャラ(円と四角)をそれぞれ100個ずつ管理しています。

地獄の変数管理

let x = [],
  y = [],
  xSpeed = [],
  ySpeed = [],
  acceleration = [];
let x2 = [],
  y2 = [],
  xSpeed2 = [],
  ySpeed2 = [],
  acceleration2 = [];

10個の配列!そして...

  • prepare()prepare2()
  • update()update2()
  • display()display2()

すべてがほぼ同じコードの繰り返し。

これが「HELL」と呼ばれる理由

  • 3種類目のキャラを追加したい → さらに5個の配列と3つの関数
  • バグを修正したい → 2箇所(または複数箇所)を修正
  • 新しい動きを追加したい → すべての update 関数を変更

この複雑さを解決する第一歩として、まず「オブジェクト(JSON)」を使ってデータを整理してみましょう。

View Source Code

let W, H, PW, PH;
const PADDING_RATIO = 0.2;
const MAX_SPEED = 10;

let x = [];
let y = [];
let xSpeed = [];
let ySpeed = [];
let acceleration = [];

let x2 = [];
let y2 = [];
let xSpeed2 = [];
let ySpeed2 = [];
let acceleration2 = [];

let MAX = 100;

function prepare() {
  for (let i = 0; i < MAX; i++) {
    x[i] = random(W);
    y[i] = random(H);
    xSpeed[i] = (Math.random() - 0.5) * MAX_SPEED;
    ySpeed[i] = (Math.random() - 0.5) * MAX_SPEED;
    acceleration[i] = 0.1;
  }
}

function prepare2() {
  for (let i = 0; i < MAX; i++) {
    x2[i] = random(W);
    y2[i] = random(H);
    xSpeed2[i] = (Math.random() - 0.5) * MAX_SPEED;
    ySpeed2[i] = (Math.random() - 0.5) * MAX_SPEED;
    acceleration2[i] = 0.1;
  }
}

function update() {
  for (let i = 0; i < MAX; i++) {
    x[i] += xSpeed[i];
    y[i] += ySpeed[i];

    if (x[i] < 0 + PW) {
      xSpeed[i] += acceleration[i];
    } else if (x[i] > W - PW) {
      xSpeed[i] -= acceleration[i];
    }

    if (y[i] < 0 + PH) {
      ySpeed[i] += acceleration[i];
    } else if (y[i] > H - PH) {
      ySpeed[i] -= acceleration[i];
    }
  }
}

function update2() {
  for (let i = 0; i < MAX; i++) {
    x2[i] += xSpeed2[i];
    y2[i] += ySpeed2[i];

    if (x2[i] < 0 + PW) {
      xSpeed2[i] += acceleration2[i];
    } else if (x2[i] > W - PW) {
      xSpeed2[i] -= acceleration2[i];
    }

    if (y2[i] < 0 + PH) {
      ySpeed2[i] += acceleration2[i];
    } else if (y2[i] > H - PH) {
      ySpeed2[i] -= acceleration2[i];
    }
  }
}

function display() {
  for (let i = 0; i < MAX; i++) {
    stroke(0);
    fill(0);
    ellipse(x[i], y[i], 10, 10);
    // text([i + "_1:", Math.floor(x[i]), Math.floor(y[i])], x[i] + 10, y[i] + 10);
  }
}

function display2() {
  for (let i = 0; i < MAX; i++) {
    stroke(0);
    fill(0);
    rectMode(CENTER)
    rect(x2[i], y2[i], 10, 10);
    // text([i + "_2:", Math.floor(x2[i]), Math.floor(y2[i])], x2[i] + 20, y2[i] + 20);
  }
}

// main

function setup() {
  createCanvas((W = windowWidth), (H = windowHeight));
  PW = W * PADDING_RATIO;
  PH = H * PADDING_RATIO;

  prepare();
  prepare2();
}

function draw() {
  background(255);

  update();
  update2();
  
  display();
  display2();
}